package org.xteam.box2text.old;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.xteam.box2text.Frame;
import org.xteam.box2text.Point;
import org.xteam.box2text.TextStruct;

public class HOperator extends Operator implements IPlaceableBox {
	
	public HOperator(Box... boxes) {
		super(boxes);
	}
	
	public HOperator(int hs, Box... boxes) {
		super(boxes);
		options.put("hs", hs);
	}

	public HOperator(int hs, List<Box> arguments) {
		super(arguments);
		options.put("hs", hs);
	}
	
	public HOperator(List<Box> arguments) {
		super(arguments);
	}

	public HOperator(Map<String, Integer> options, List<Box> arguments) {
		super(options, arguments);
	}
	
	public Box removeVertical(boolean removeRow) {
		return new HOperator(options, removeVertical(arguments, removeRow));
	}

	public int width(Frame frame) {
		int sum = 0;
		boolean isFirst = true;
		for (Box barg : arguments) {
			if ( ! barg.isEmpty()) {
				IPlaceableBox arg = (IPlaceableBox) barg;
				if (isFirst) {
					isFirst = false;
					sum = arg.width(frame);
				} else {
					sum += frame.getHs(options) + arg.width(frame);
				}
			}
		}
		return sum;
	}

	public TextStruct place(Frame frame, TextStruct textStruct, int context) {
		if (isEmpty())
			return textStruct;
		if (size() == 1) {
			return ((IPlaceableBox)arguments.get(0))
				.place(frame.setTs(options()), textStruct, OperatorKinds.H);
		}
		int Hs = frame.getHs(options());
		Frame Frame2 = frame.setTs(options());
		return hplace(arguments, Hs, Frame2, textStruct);
	}
	
	protected static TextStruct hplace(List<Box> boxes, int Hs, Frame f, TextStruct textStruct) {
		for (Box b : boxes) {
			textStruct = ((IPlaceableBox)b).place(f, textStruct, OperatorKinds.H);
			f = f.hsep(textStruct.point(), Hs);
		}
		return textStruct;
	}

	public Point length(Frame frame, int context) {
		if (isEmpty()) {
			return new Point(0,0);
		}
		return hlength(arguments, frame.getHs(options), frame);
	}

	private static Point hlength(List<Box> arguments, int hs, Frame frame) {
		Point bp = null;
		for (Box arg : arguments) {
			if (bp == null) {
				bp = ((IPlaceableBox)arg).length(frame, OperatorKinds.H);
			} else {
				bp = h(bp, ((IPlaceableBox)arg).length(frame, OperatorKinds.H), hs);
			}
		}
		return bp;
	}
	
	private static Point h(Point p1, Point p2, int hs) {
		if (p2.isZero())
			return p1;
		if (p1.isZero())
			return p2;
		return new Point(p1.width() + hs + p2.width(), p1.height() + p2.height());
	}

	@Override
	public List<Box> normalizeGroups(boolean splice) {
		return Arrays.asList(new Box[] { new HOperator(options, normalizeChildren(true)) });
	}

}
